<template>
  <div class="project-menu-container">
    <div class="project-title-container">
      <div class="project-title">{{ project.title }}</div>
      <div class="project-describe">描述：{{ project.describe }}</div>
    </div>
    <div class="project-button-container">
      <a-button class="back" type="primary" @click="() => {$router.go(-1)}">返回</a-button>
      <a-button class="create" type="primary" @click="viewCreateApi">新建接口/目录</a-button>
    </div>
    <div class="project-apis-container">
      <a-spin tip="Loading..." :spinning="loading" class="project-apis-loading">
        <tree ref="treeDom" :nodes="apis" :setting="treeSetting" @onCreated="treeCreate"></tree>
        <a-empty v-if="apis.length === 0" class="project-apis-empty"/>
      </a-spin>
    </div>

    <!-- 右键接口菜单 -->
    <div ref="rightMenu" class="right-menu">
      <div class="menu-item" @click="viewUpdateApi">编辑</div>
      <div class="menu-item" @click="copyApi">复制</div>
      <div class="menu-item del" @click="delApi">删除</div>
    </div>
    <!--创建接口/目录表单-->
    <api-form ref="createApi" title="创建接口/目录" :visible="createVisible" @cancel="cancelCreateApi" @create="createApi"/>
    <!--编辑接口/目录表单-->
    <api-form ref="updateApi" title="编辑接口/目录" :visible="updateVisible" @cancel="cancelUpdateApi" @create="updateApi"/>
  </div>
</template>

<script>
import ApiForm from '@/component/ApiForm'
import Tree from 'vue-giant-tree'

export default {
  name: 'ProjectMenu',
  components: { ApiForm, Tree },
  props: ['project'],
  data () {
    return {
      loading: true,
      createVisible: false,
      updateVisible: false,
      treeSetting: {
        data: { keep: { leaf: true, parent: true }, simpleData: { enable: true, idKey: 'id', pIdKey: 'pId', rootPId: 0 } },
        edit: { enable: true, showRemoveBtn: false, showRenameBtn: false, drag: { autoOpenTime: 0 } },
        view: { showIcon: true, showLine: false, expandSpeed: 'fast' },
        callback: { onRightClick: this.rightClickApi, onDrop: this.drop, onClick: this.clickApi }
      },
      treeObj: null, // zTree的根对象，
      apis: [], // 接口列表：[{ id: 1, pId: 0, projectId1: 1, order: 0, name: '测试接口1', isParent: true, iconSkin: 'POST' }]
      expandNode: [] // zTree默认展开的节点
    }
  },
  watch: {
    project () {
      this.apiLists()
    }
  },
  methods: {
    // zTree创建成功后的事件（用于初始化默认展开节点）
    treeCreate () {
      this.treeObj = this.$refs.treeDom.ztreeObj
      this.expandNode.forEach((item) => {
        this.treeObj.expandNode(this.treeObj.getNodeByParam('id', item.id, null), true, false, false)
      })
      // 滚动动画
      // if (this.treeNode) {
      //   setTimeout(() => {
      //     this.$el.querySelector('#' + this.treeObj.getNodeByParam('id', this.treeNode.id, null).tId).scrollIntoView({
      //       behavior: 'smooth',
      //       block: 'start',
      //       inline: 'nearest'
      //     })
      //   }, 200)
      // }
    },
    // 获取接口列表
    apiLists () {
      this.loading = true
      this.expandNode = this.treeObj.getNodesByFilter((node) => {
        return node.open
      })
      this.$db.api.where({
        projectId: this.project.id
      }).sortBy('order').then((res) => {
        this.apis = res
        this.loading = false
      })
    },
    // 显示 创建 接口模态框
    viewCreateApi () {
      this.createVisible = true
    },
    // 显示 编辑 接口模态框
    viewUpdateApi () {
      this.updateVisible = true
      this.$nextTick(() => { // DOM更新后传递表单
        const param = Object.assign({}, this.treeNode)
        this.$refs.updateApi.form.setFieldsValue({
          id: param.id,
          pId: param.pId,
          projectId: param.projectId,
          order: param.order,
          iconSkin: param.iconSkin,
          name: param.name,
          isParent: param.isParent
        })
      })
    },
    // 隐藏 创建 接口模态框
    cancelCreateApi () {
      this.createVisible = false
    },
    // 隐藏 编辑 接口模态框
    cancelUpdateApi () {
      this.updateVisible = false
    },
    // 点击提交 创建 接口
    createApi () {
      this.$refs.createApi.form.validateFields((err, values) => {
        if (!err) {
          this.$db.api.where({
            pId: 0,
            projectId: this.project.id
          }).toArray().then((res) => {
            const num = Number((this.$_.maxBy(res, 'order') || { order: -1 }).order) + 1
            values.pId = 0
            values.projectId = this.project.id
            values.order = num
            values.iconSkin = values.isParent ? 'dir' : 'get'
            this.$db.api.add(values).then((id) => {
              this.cancelCreateApi()
              this.apiLists()
            })
          })
        }
      })
    },
    // 点击提交 编辑 接口
    updateApi () {
      this.$refs.updateApi.form.validateFields((err, values) => {
        if (!err) {
          values.iconSkin = values.isParent ? 'dir' : 'get'
          this.$db.api.put(values).then((id) => {
            this.cancelUpdateApi()
            this.apiLists()
          })
        }
      })
    },
    // 左键点击接口
    clickApi (event, treeId, treeNode) {
      if (!treeNode.isParent) {
        console.log(event, treeNode, treeNode)
      } else {
        this.treeObj.expandNode(treeNode, true, false, true)
      }
    },
    // 右键点击接口
    rightClickApi (event, treeId, treeNode) {
      this.treeNode = treeNode
      const rightMenuDom = this.$refs.rightMenu
      rightMenuDom.style.visibility = 'visible'
      rightMenuDom.style.opacity = '1'
      rightMenuDom.style.top = event.clientY + 'px'
      rightMenuDom.style.left = event.clientX + 'px'
      document.addEventListener('click', () => {
        rightMenuDom.style.visibility = 'hidden'
        rightMenuDom.style.opacity = '0'
      })
    },
    // 删除接口
    delApi () {
      this.$db.api.delete(this.treeNode.id).then(() => {
        this.apiLists()
      })
    },
    // 复制接口
    copyApi () {
      this.$db.api.get(this.treeNode.id).then((res) => {
        const param = Object.assign({}, res)
        delete param.id
        param.name = param.name + '- copy'
        this.$db.api.add(param).then((id) => {
          this.apiLists()
        })
      })
    },
    // 拖拽排序
    drop (event, treeId, treeNodes, targetNode, moveType) {
      this.treeNode = treeNodes[0]
      const apis = []
      this.treeObj.transformToArray(this.treeObj.getNodes()).forEach((item, index) => {
        apis[index] = {
          id: item.id,
          pId: item.pId,
          projectId: item.projectId,
          order: index,
          name: item.name,
          isParent: item.isParent,
          iconSkin: item.iconSkin
        }
      })
      this.$db.api.bulkPut(apis).then(() => {
        this.apiLists()
      })
    },
    // 测试填充数据
    fullData () {
      let order = 0
      const icon = ['get', 'pos', 'put', 'pat', 'del']
      for (let i = 1; i <= 30; i++) {
        this.$db.api.add({ pId: 0, projectId: this.project.id, order: order++, name: '测试目录' + i, isParent: true, iconSkin: 'dir' }).then(id => {
          for (let j = 1; j <= 5; j++) {
            this.$db.api.add({ pId: id, projectId: this.project.id, order: order++, name: '测试目录' + i + '-' + j, isParent: true, iconSkin: 'dir' }).then(id => {
              let y
              for (y = 1; y <= 5; y++) {
                this.$db.api.add({ pId: id, projectId: this.project.id, order: order++, name: '测试接口' + i + '-' + j + '-' + y, isParent: false, iconSkin: icon[Math.floor((Math.random() * icon.length))] })
              }
            })
          }
          for (let z = 1; z <= 5; z++) {
            this.$db.api.add({ pId: id, projectId: this.project.id, order: order++, name: '测试接口' + i + '-' + z, isParent: false, iconSkin: icon[Math.floor((Math.random() * icon.length))] })
          }
        })
      }
    }
  }
}
</script>

<style scoped lang="less">
@titleContainerHeight: 120px;
@buttonContainerHeight: 70px;
.project-menu-container {
  width: 100%;
  height: 100%;
  padding: 20px 20px;
}

.project-title-container {
  width: 100%;
  height: @titleContainerHeight;
  box-shadow: black 0 0 5px 0;
  color: white;
  background-color: #001529;
  border-radius: 10px;
  transition: 0.3s;
  box-sizing: border-box;
}

.project-title-container:hover {
  box-shadow: black 0 0 15px 0;
}

.project-title {
  padding: 20px;
  font-size: 18px;
  font-weight: bold;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

.project-describe {
  color: #c2c2c2;
  font-size: 14px;
  padding: 0 20px;
  display: -webkit-box;
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.project-button-container {
  height: @buttonContainerHeight;
  display: flex;
  justify-content: space-between;
  align-items: center;
  overflow: hidden;

  .back {
    width: 25%;
    padding: 0;
  }

  .create {
    width: 70%;
    padding: 0;
  }
}

.project-apis-container {
  width: 100%;
  height: calc(100% - @titleContainerHeight - @buttonContainerHeight);
  overflow: auto;
  background-color: #eaeaea;
  border-radius: 5px;
}

.project-apis-loading {
  width: 100%;
  height: 100%;
}

.project-apis-empty {
  padding-top: 50px;
}

/deep/ .dir_ico_open {
  background-image: url('../assets/img/icon/folder-open.png');
  background-size: 95% 95%;
}

/deep/ .dir_ico_close {
  background-image: url('../assets/img/icon/folder-close.png');
  background-size: 95% 95%;
}

/deep/ .get_ico_docu {
  background-image: url('../assets/img/icon/get.png');
  background-size: 95% 85%;
}

/deep/ .pos_ico_docu {
  background-image: url('../assets/img/icon/pos.png');
  background-size: 95% 85%;
}

/deep/ .put_ico_docu {
  background-image: url('../assets/img/icon/put.png');
  background-size: 95% 85%;
}

/deep/ .pat_ico_docu {
  background-image: url('../assets/img/icon/pat.png');
  background-size: 95% 85%;
}

/deep/ .del_ico_docu {
  background-image: url('../assets/img/icon/del.png');
  background-size: 95% 85%;
}

.right-menu {
  width: 60px;
  position: fixed;
  overflow: hidden;
  border-radius: 5px;
  box-shadow: #001529 0 0 8px -2px;
  transition: 0.3s;
  visibility: hidden;
  opacity: 0;

  .menu-item {
    border-radius: 5px;
    background-color: #ffffff;
    cursor: pointer;
    transition: 0.3s;
    color: #000000;
    text-align: center;
    border: 1px solid #cecece;
  }

  .menu-item:hover {
    background-color: #f6f6f6;
  }

  .del {
    color: #f5222d;
  }
}

</style>
